package com.wanggy.mystore.service.impl;

import com.wanggy.mystore.entity.Address;
import com.wanggy.mystore.entity.User;
import com.wanggy.mystore.mapper.AddressMapper;
import com.wanggy.mystore.mapper.UserMapper;
import com.wanggy.mystore.service.IAddressService;
import com.wanggy.mystore.service.IDistrictService;
import com.wanggy.mystore.service.ex.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.rmi.AccessException;
import java.util.Collections;
import java.util.Date;
import java.util.List;


/**
 * 收货地址业务层实现方法
 */
@Service
public class AddressServiceImpl implements IAddressService {
    @Autowired
    private AddressMapper addressMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private IDistrictService districtService;

    /**
     * 为了方便日后修改最大收货地址数量，可以在配置文件中进行配置
     */
    @Value("${user.address.max-count}")
    private Integer maxCount;

    /**
     * 新增收货地址
     * @param uid 用户uid
     * @param username 用户username
     * @param address 收货地址数据
     */
    @Override
    public void addNewAddress(Integer uid, String username, Address address) {
        //根据uid查询当前用户数据
        User user = userMapper.findByUid(uid);
        //判断当前用户是否存在
        if(user == null || user.getIsDelete() == 1){
            throw new UserNotFoundException("用户数据不存在");
        }
        //统计当前用户的收货地址数
        Integer addressCount = addressMapper.countByUid(uid);
        //判断收货地址数量是否超出显示
        if(addressCount >= maxCount){
            throw new AddressCountLimitException("用户收货地址超出上限");
        }
        //封装处理address数据
        address.setUid(uid);
        Integer isDefault = addressCount == 0 ? 1 : 0;  //1表示默认收货地址，0表示非默认收货地址
        address.setIsDefault(isDefault);

        //补全四项操作日志
        address.setCreatedUser(username);
        address.setCreatedTime(new Date());
        address.setModifiedUser(username);
        address.setModifiedTime(new Date());

        //补全省市区名称
        address.setProvinceName(districtService.findNameByCode(address.getProvinceCode()));
        address.setCityName(districtService.findNameByCode(address.getCityCode()));
        address.setAreaName(districtService.findNameByCode(address.getAreaCode()));

        //调用插入收货地址的方法
        Integer rows = addressMapper.insert(address);
        if (rows != 1){
            throw new InsertException("插入用户的收货地址时产生未知异常");
        }
    }

    /**
     * 根据用户uid获取收货地址数据
     * @param uid 用户uid
     * @return 收货地址数据
     */
    @Override
    public List<Address> getByUid(Integer uid) {
        List<Address> addressList = addressMapper.findByUid(uid);
        /**
         * 收货地址列表在前端只展示四个数据，这里让其他值为空降低数据量
         * ProviceName,CityName,AreaName,aid,tel(确定订单页展示用户地址时用到tel)
         * 在展示地址列表用不到，但是后边提交订单时的地址会用到，所以这里不设置为null
         */
        for (Address address : addressList) {
            address.setUid(null);
            address.setProvinceCode(null);
            address.setCityCode(null);
            address.setAreaCode(null);
            address.setZip(null);
            address.setIsDefault(null);
            address.setCreatedUser(null);
            address.setCreatedTime(null);
            address.setModifiedUser(null);
            address.setModifiedTime(null);
        }
        return addressList;
    }


    /**
     * 修改某个用户的某条收货地址数据为默认收货地址
     * @param aid 收货地址aid
     * @param uid 用户uid
     * @param modifiedUser 修改执行人
     */
    @Override
    @Transactional
    public void setDefault(Integer aid, Integer uid, String modifiedUser) {
        /**
         * 1.检查aid对应的收货地址是否存在，不存在抛AddressNotFoundException异常
         * 2.检查aid对应的收货地址是不是当前用户的收货地址，不属于该用户则抛出AccessDeniedException异常
         * 3.检查数据更新数量是否正常，不正常则抛UpdateException异常
         */
        Address address = addressMapper.findByAid(aid);
        if(address == null){
            throw new AddressNotFoundException("收货地址不存在");
        }
        if(address.getUid() != uid){
            throw new AccessDeniedException("非法数据访问");
        }
        //将当前用户的所有收货地址设置为非默认地址
        Integer rows = addressMapper.updateNoDefault(uid);
        if(rows < 1){
            throw new UpdateException("更新数据时产生未知的异常");
        }
        //将当前收货地址设置为默认收货地址
        rows = addressMapper.updateDefaultByAid(aid, modifiedUser, new Date());
        if(rows != 1){
            throw new UpdateException("更新数据时产生未知的异常");
        }
    }


    /**
     * 根据aid删除收货地址数据
     * @param aid 收货地址aid
     * @param uid 用户aid
     * @param username 修改执行者
     */
    @Override
    public void deleteByAid(Integer aid, Integer uid, String username) {
        /**
         * 1.查询收货地址数据判断是否存在，不存在抛AddressNotFoundException
         * 2.判断收货地址归属，有问题抛AccessDeniedException
         * 3.判断收货地址是否为默认，如果是则进行特殊业务处理（重新选择并设置默认地址）
         * 4.判断收货地址是否删除成功，没有则抛DeleteException
         */
        Address address = addressMapper.findByAid(aid);
        if(address == null){
            throw new AddressNotFoundException("收货地址不错在");
        }
        if(address.getUid() != uid){
            throw new AccessDeniedException("非法数据访问");
        }

        Integer rows = addressMapper.deleteByAid(aid);
        if(rows != 1){
            throw new DeleteException("删除数据时产生未知的异常");
        }

        if(address.getIsDefault() == 0){
            return;
        }

        Integer count = addressMapper.countByUid(uid);
        if(count == 0){
            return;
        }
        Address lastModifedAddress = addressMapper.findLastModifedByUid(uid);
        //设置新的默认收货地址
       rows = addressMapper.updateDefaultByAid(lastModifedAddress.getAid(),username,new Date());
       if(rows != 1){
           throw new UpdateException("更新数据时产生异常");
       }
    }
}